package icu.cqcai.xinsi.controller;

import icu.cqcai.xinsi.domain.ChatMessage;
import icu.cqcai.xinsi.domain.ChatSession;
import icu.cqcai.xinsi.service.ChatService;
import icu.cqcai.xinsi.service.CozeApiService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.http.HttpStatus;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 聊天控制器 - 处理与智能助手的对话功能
 * 
 * 主要功能：
 * 1. 处理用户与AI助手的消息发送和接收
 * 2. 支持文件上传并进行智能分析
 * 3. 管理用户的聊天会话和消息历史
 * 4. 提供聊天记录搜索功能
 * 5. 区分登录用户和匿名用户的不同处理逻辑
 * 
 * 技术特点：
 * - 支持RESTful API接口
 * - 集成扣子(Coze) AI服务
 * - 支持多种文件格式上传（PDF、DOC、DOCX、TXT、图片）
 * - 登录用户数据持久化存储，匿名用户临时处理
 * 
 * @author xinsi团队
 * @version 1.0
 * @since 2024
 */
@Controller
@RequestMapping("/chat")
public class ChatController {

    /**
     * 日志记录器 - 用于记录聊天功能的详细操作日志
     */
    private static final Logger logger = LoggerFactory.getLogger(ChatController.class);

    /**
     * 聊天服务 - 处理登录用户的聊天逻辑和数据库操作
     * 包括会话管理、消息存储、历史记录查询等功能
     */
    @Autowired
    private ChatService chatService;

    /**
     * 扣子API服务 - 直接调用Coze AI接口
     * 主要用于匿名用户的AI对话和文件处理
     */
    @Autowired
    private CozeApiService cozeApiService;

    /**
     * 聊天页面入口
     * 
     * 功能说明：
     * - 返回聊天页面模板
     * - 支持登录用户和匿名用户访问
     * 
     * @return 聊天页面模板名称
     */
    @GetMapping
    public String chatPage() {
        logger.info("=== 用户访问聊天页面 ===");
        return "chat";
    }

    /**
     * 发送消息到智能助手
     * 
     * 核心功能：
     * 1. 接收用户文本消息
     * 2. 根据用户身份选择不同的处理策略
     * 3. 调用AI服务获取智能回复
     * 4. 返回统一格式的响应数据
     * 
     * 处理逻辑：
     * - 登录用户：通过ChatService处理，数据存储到数据库
     * - 匿名用户：直接调用CozeAPI，不进行数据持久化
     * 
     * @param request 包含消息内容和用户名的请求体
     *                - message: 用户发送的消息内容（必填）
     *                - username: 用户名，为空或"anonymous_user"表示匿名用户
     * @return ResponseEntity 包含AI回复和处理状态的响应
     */
    @PostMapping("/send")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> sendMessage(@RequestBody Map<String, String> request) {
        logger.info("=== 接收到发送消息请求 ===");
        
        // 初始化响应对象
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 提取请求参数
            String message = request.get("message");
            String username = request.get("username");
            
            logger.info("用户: {}, 消息长度: {}", 
                       username != null ? username : "匿名用户", 
                       message != null ? message.length() : 0);
            
            // 验证消息内容不能为空
            if (message == null || message.trim().isEmpty()) {
                logger.warn("消息内容为空，拒绝处理");
                response.put("success", false);
                response.put("error", "消息不能为空");
                return ResponseEntity.badRequest().body(response);
            }
            
            String aiResponse;
            
            // 根据用户类型选择不同的处理策略
            if (username == null || username.trim().isEmpty() || "anonymous_user".equals(username)) {
                // 匿名用户处理逻辑：
                // 1. 生成临时用户ID，避免会话冲突
                // 2. 直接调用CozeAPI，不保存到数据库
                // 3. 适合临时访客或不需要历史记录的场景
                String cozeUserId = "anonymous_" + System.currentTimeMillis();
                logger.info("匿名用户处理，生成临时ID: {}", cozeUserId);
                
                aiResponse = cozeApiService.sendMessage(message.trim(), cozeUserId);
                logger.info("匿名用户消息处理完成，AI回复长度: {}", aiResponse != null ? aiResponse.length() : 0);
            } else {
                // 登录用户处理逻辑：
                // 1. 使用ChatService进行完整的会话管理
                // 2. 消息和回复都会保存到数据库
                // 3. 支持历史记录查询和会话管理
                logger.info("登录用户处理，用户名: {}", username);
                
                aiResponse = chatService.sendMessage(username, message.trim());
                logger.info("登录用户消息处理完成，用户: {}, AI回复长度: {}", 
                           username, aiResponse != null ? aiResponse.length() : 0);
            }
            
            // 构建成功响应
            response.put("success", true);
            response.put("message", aiResponse);
            response.put("timestamp", System.currentTimeMillis());
            
            logger.info("消息发送成功，响应已构建");
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            // 异常处理和日志记录
            logger.error("处理聊天消息失败: {}", e.getMessage(), e);
            
            // 构建错误响应，避免向用户暴露内部错误信息
            response.put("success", false);
            response.put("error", "服务器内部错误，请稍后重试");
            return ResponseEntity.internalServerError().body(response);
        }
    }

    /**
     * 发送消息到智能助手（支持文件上传）
     * 
     * 增强功能：
     * 1. 支持文本消息 + 文件附件的组合发送
     * 2. 智能文件格式验证和大小限制
     * 3. 文件上传到OSS云存储
     * 4. AI分析文件内容并生成回复
     * 
     * 支持的文件格式：
     * - 文档类：PDF、DOC、DOCX、TXT
     * - 图片类：JPG、PNG、GIF等所有图片格式
     * 
     * 安全限制：
     * - 文件大小限制：10MB
     * - 严格的文件类型检查
     * 
     * @param message 文本消息内容（可选，与文件至少选择一项）
     * @param username 用户名，决定数据处理策略
     * @param file 上传的文件（可选，与消息至少选择一项）
     * @return ResponseEntity 包含AI分析结果和处理状态
     */
    @PostMapping("/send-with-file")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> sendMessageWithFile(
            @RequestParam("message") String message,
            @RequestParam("username") String username,
            @RequestParam(value = "file", required = false) MultipartFile file) {
        
        logger.info("=== 接收到带文件的消息请求 ===");
        logger.info("用户: {}, 消息长度: {}, 文件: {}", 
                   username != null ? username : "匿名用户",
                   message != null ? message.length() : 0,
                   file != null && !file.isEmpty() ? file.getOriginalFilename() : "无文件");
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 验证输入：消息和文件不能都为空
            if ((message == null || message.trim().isEmpty()) && (file == null || file.isEmpty())) {
                logger.warn("消息和文件都为空，拒绝处理");
                response.put("success", false);
                response.put("error", "消息内容或文件不能都为空");
                return ResponseEntity.badRequest().body(response);
            }
            
            // 文件验证逻辑
            if (file != null && !file.isEmpty()) {
                String contentType = file.getContentType();
                long fileSize = file.getSize();
                
                logger.info("文件验证 - 名称: {}, 类型: {}, 大小: {} bytes", 
                           file.getOriginalFilename(), contentType, fileSize);
                
                // 检查文件类型是否在允许列表中
                if (contentType == null || (!contentType.equals("application/pdf") && 
                    !contentType.equals("application/msword") && 
                    !contentType.equals("application/vnd.openxmlformats-officedocument.wordprocessingml.document") &&
                    !contentType.equals("text/plain") &&
                    !contentType.startsWith("image/"))) {
                    logger.warn("不支持的文件类型: {}", contentType);
                    response.put("success", false);
                    response.put("error", "仅支持PDF、DOC、DOCX、TXT和图片格式的文件");
                    return ResponseEntity.badRequest().body(response);
                }
                
                // 检查文件大小限制（10MB = 10 * 1024 * 1024 bytes）
                if (fileSize > 10 * 1024 * 1024) {
                    logger.warn("文件大小超限: {} bytes > 10MB", fileSize);
                    response.put("success", false);
                    response.put("error", "文件大小不能超过10MB");
                    return ResponseEntity.badRequest().body(response);
                }
                
                logger.info("文件验证通过");
            }
            
            String aiResponse;
            String userMessage = message != null ? message.trim() : "";
            
            // 如果有文件，智能组合文本和文件信息
            if (file != null && !file.isEmpty()) {
                if (userMessage.isEmpty()) {
                    // 仅有文件时，生成默认分析请求
                    userMessage = "请帮我分析这个文件：" + file.getOriginalFilename();
                    logger.info("仅文件上传，生成默认分析请求");
                } else {
                    // 文本+文件时，在消息后添加文件信息
                    userMessage = userMessage + "\n\n[附件：" + file.getOriginalFilename() + "]";
                    logger.info("文本+文件组合消息");
                }
            }
            
            // 根据用户类型选择处理策略
            if (username == null || username.trim().isEmpty() || "anonymous_user".equals(username)) {
                // 匿名用户的文件处理流程
                String cozeUserId = "anonymous_" + System.currentTimeMillis();
                logger.info("匿名用户文件处理，临时ID: {}", cozeUserId);
                
                if (file != null && !file.isEmpty()) {
                    logger.info("开始上传文件到OSS");
                    // 文件上传到OSS并获取访问URL
                    String fileUrl = cozeApiService.uploadFileToOSS(file);
                    if (fileUrl != null && !fileUrl.isEmpty()) {
                        logger.info("文件上传成功，URL: {}", fileUrl);
                        // 发送包含文件URL的消息给AI
                        aiResponse = cozeApiService.sendMessageWithFile(userMessage, fileUrl, cozeUserId, null);
                        logger.info("AI文件分析完成，回复长度: {}", aiResponse != null ? aiResponse.length() : 0);
                    } else {
                        // 文件上传失败的处理
                        logger.error("文件上传到OSS失败");
                        aiResponse = "文件上传失败，请检查文件格式是否正确。";
                    }
                } else {
                    // 仅文本消息的处理
                    logger.info("匿名用户仅文本消息处理");
                    aiResponse = cozeApiService.sendMessage(userMessage, cozeUserId);
                    logger.info("AI文本处理完成，回复长度: {}", aiResponse != null ? aiResponse.length() : 0);
                }
            } else {
                // 登录用户的文件处理流程
                logger.info("登录用户文件处理，用户: {}", username);
                
                if (file != null && !file.isEmpty()) {
                    logger.info("通过ChatService处理文件消息");
                    // 通过ChatService处理，包含数据库存储
                    aiResponse = chatService.sendMessageWithFile(username, userMessage, file);
                    logger.info("ChatService文件处理完成，用户: {}, 回复长度: {}", 
                               username, aiResponse != null ? aiResponse.length() : 0);
                } else {
                    logger.info("通过ChatService处理文本消息");
                    // 仅文本消息，通过ChatService处理
                    aiResponse = chatService.sendMessage(username, userMessage);
                    logger.info("ChatService文本处理完成，用户: {}, 回复长度: {}", 
                               username, aiResponse != null ? aiResponse.length() : 0);
                }
            }
            
            // 构建成功响应
            response.put("success", true);
            response.put("message", aiResponse);
            response.put("timestamp", System.currentTimeMillis());
            
            logger.info("带文件消息处理成功");
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            // 异常处理：记录详细错误日志，返回用户友好的错误信息
            logger.error("处理带文件的聊天消息失败: {}", e.getMessage(), e);
            
            response.put("success", false);
            response.put("error", "服务器内部错误，请稍后重试");
            return ResponseEntity.internalServerError().body(response);
        }
    }

    /**
     * 获取用户的聊天会话列表
     * 
     * 功能说明：
     * 1. 查询用户的所有聊天会话
     * 2. 按时间倒序排列，最新会话在前
     * 3. 匿名用户返回空列表（会话由前端本地存储管理）
     * 
     * 应用场景：
     * - 聊天界面左侧会话列表的数据源
     * - 用户历史对话的快速访问入口
     * 
     * @param username 用户名，用于查询该用户的会话
     * @return ResponseEntity 包含会话列表的响应数据
     */
    @GetMapping("/sessions")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> getUserSessions(@RequestParam String username) {
        logger.info("=== 获取用户会话列表请求 ===");
        logger.info("请求用户: {}", username != null ? username : "匿名用户");
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 匿名用户特殊处理：返回空列表
            // 原因：匿名用户的会话数据不存储在服务器，由前端本地存储管理
            if (username == null || username.trim().isEmpty() || "anonymous_user".equals(username)) {
                logger.info("匿名用户请求会话列表，返回空列表");
                response.put("success", true);
                response.put("sessions", List.of());
                return ResponseEntity.ok(response);
            }
            
            // 登录用户：从数据库查询会话列表
            logger.info("查询登录用户会话列表: {}", username);
            List<ChatSession> sessions = chatService.getUserSessions(username);
            
            response.put("success", true);
            response.put("sessions", sessions);
            
            logger.info("成功获取用户会话列表，用户: {}, 会话数量: {}", username, sessions.size());
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            // 异常处理：记录错误并返回友好的错误信息
            logger.error("获取用户会话列表失败，用户: {}, 错误: {}", username, e.getMessage(), e);
            response.put("success", false);
            response.put("error", "获取会话列表失败");
            return ResponseEntity.internalServerError().body(response);
        }
    }

    /**
     * 获取指定会话的消息历史
     * 
     * 分页查询功能：
     * 1. 支持分页查询，避免大量数据一次性加载
     * 2. 按时间顺序排列消息
     * 3. 可配置每页大小，默认50条
     * 
     * 权限验证：
     * - 只能查询属于该用户的会话消息
     * - 匿名用户返回空列表
     * 
     * @param sessionId 会话ID，指定要查询的会话
     * @param page 页码，从1开始，默认第1页
     * @param size 每页大小，默认50条记录
     * @param username 用户名，用于权限验证
     * @return ResponseEntity 包含消息列表的分页数据
     */
    @GetMapping("/sessions/{sessionId}/messages")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> getSessionMessages(@PathVariable Long sessionId,
                                                                 @RequestParam(defaultValue = "1") int page,
                                                                 @RequestParam(defaultValue = "50") int size,
                                                                 @RequestParam(required = false) String username) {
        logger.info("=== 获取会话消息历史请求 ===");
        logger.info("会话ID: {}, 用户: {}, 页码: {}, 每页大小: {}", 
                   sessionId, username != null ? username : "匿名用户", page, size);
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 匿名用户处理：返回空列表
            // 匿名用户的消息由前端本地存储管理，不存储在服务器
            if (username == null || username.trim().isEmpty() || "anonymous_user".equals(username)) {
                logger.info("匿名用户请求会话消息，返回空列表");
                response.put("success", true);
                response.put("messages", List.of());
                return ResponseEntity.ok(response);
            }
            
            // 登录用户：执行分页查询
            logger.info("查询登录用户会话消息: 用户={}, 会话ID={}", username, sessionId);
            List<ChatMessage> messages = chatService.getSessionMessages(sessionId, page, size);
            
            response.put("success", true);
            response.put("messages", messages);
            
            logger.info("成功获取会话消息，会话ID: {}, 消息数量: {}", sessionId, messages.size());
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            // 异常处理：可能的异常包括会话不存在、权限不足等
            logger.error("获取会话消息失败，会话ID: {}, 用户: {}, 错误: {}", 
                        sessionId, username, e.getMessage(), e);
            response.put("success", false);
            response.put("error", "获取消息历史失败");
            return ResponseEntity.internalServerError().body(response);
        }
    }

    /**
     * 删除聊天会话
     * 
     * 安全机制：
     * 1. 软删除或硬删除（根据业务需求）
     * 2. 删除会话时同时删除相关联的所有消息
     * 3. 操作不可逆，需要前端二次确认
     * 
     * @param sessionId 要删除的会话ID
     * @return ResponseEntity 删除操作的结果状态
     */
    @DeleteMapping("/sessions/{sessionId}")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> deleteSession(@PathVariable Long sessionId) {
        logger.info("=== 删除聊天会话请求 ===");
        logger.info("要删除的会话ID: {}", sessionId);
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 执行删除操作
            logger.info("开始删除会话: {}", sessionId);
            boolean success = chatService.deleteSession(sessionId);
            
            response.put("success", success);
            response.put("message", success ? "会话删除成功" : "会话删除失败");
            
            if (success) {
                logger.info("会话删除成功，会话ID: {}", sessionId);
            } else {
                logger.warn("会话删除失败，会话ID: {}", sessionId);
            }
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            // 异常处理：可能的异常包括会话不存在、外键约束等
            logger.error("删除会话异常，会话ID: {}, 错误: {}", sessionId, e.getMessage(), e);
            response.put("success", false);
            response.put("error", "删除会话失败");
            return ResponseEntity.internalServerError().body(response);
        }
    }

    /**
     * 搜索聊天记录
     * 
     * 智能搜索功能：
     * 1. 支持关键词模糊搜索
     * 2. 搜索范围包括用户消息和AI回复
     * 3. 按相关性和时间排序
     * 4. 限制搜索结果数量，避免性能问题
     * 
     * 应用场景：
     * - 用户查找历史对话内容
     * - 快速定位特定主题的讨论
     * 
     * @param username 用户名，限制搜索范围
     * @param keyword 搜索关键词，支持模糊匹配
     * @param limit 结果数量限制，默认20条
     * @return ResponseEntity 包含搜索结果的响应数据
     */
    @GetMapping("/search")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> searchMessages(@RequestParam String username,
                                                             @RequestParam String keyword,
                                                             @RequestParam(defaultValue = "20") int limit) {
        logger.info("=== 搜索聊天记录请求 ===");
        logger.info("用户: {}, 关键词: {}, 限制数量: {}", username, keyword, limit);
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 执行关键词搜索
            logger.info("开始搜索聊天记录，用户: {}, 关键词: {}", username, keyword);
            List<ChatMessage> messages = chatService.searchMessages(username, keyword, limit);
            
            response.put("success", true);
            response.put("messages", messages);
            
            logger.info("搜索完成，用户: {}, 关键词: {}, 找到结果: {} 条", 
                       username, keyword, messages.size());
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            // 异常处理：可能的异常包括SQL查询错误、关键词格式问题等
            logger.error("搜索聊天记录失败，用户: {}, 关键词: {}, 错误: {}", 
                        username, keyword, e.getMessage(), e);
            response.put("success", false);
            response.put("error", "搜索失败");
            return ResponseEntity.internalServerError().body(response);
        }
    }

    /**
     * 获取用户聊天统计信息
     * 
     * 统计维度：
     * 1. 会话总数：用户创建的对话会话数量
     * 2. 消息总数：用户发送和接收的消息总数
     * 3. 可扩展其他维度：平均会话长度、活跃天数等
     * 
     * 应用场景：
     * - 用户个人数据看板
     * - 系统使用情况分析
     * 
     * @param username 用户名，指定要统计的用户
     * @return ResponseEntity 包含统计数据的响应
     */
    @GetMapping("/statistics")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> getChatStatistics(@RequestParam String username) {
        logger.info("=== 获取用户聊天统计信息请求 ===");
        logger.info("统计用户: {}", username);
        
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 获取用户的聊天统计数据
            logger.info("开始统计用户聊天数据: {}", username);
            ChatService.ChatStatistics stats = chatService.getUserChatStatistics(username);
            
            response.put("success", true);
            response.put("sessionCount", stats.getSessionCount());
            response.put("messageCount", stats.getMessageCount());
            
            logger.info("统计完成，用户: {}, 会话数: {}, 消息数: {}", 
                       username, stats.getSessionCount(), stats.getMessageCount());
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            // 异常处理：统计查询失败
            logger.error("获取用户聊天统计失败，用户: {}, 错误: {}", username, e.getMessage(), e);
            response.put("success", false);
            response.put("error", "获取统计信息失败");
            return ResponseEntity.internalServerError().body(response);
        }
    }

    /**
     * 创建新对话会话
     * 
     * 会话管理逻辑：
     * 1. 为用户创建新的对话会话
     * 2. 自动生成会话标题（可基于首条消息）
     * 3. 初始化会话状态和时间戳
     * 
     * 特殊处理：
     * - 匿名用户生成临时用户标识
     * - 登录用户关联到用户账户
     * 
     * @param request 包含用户名的请求体
     * @return ResponseEntity 创建结果状态
     */
    @PostMapping("/new-session")
    @ResponseBody
    public ResponseEntity<Map<String, Object>> createNewSession(@RequestBody Map<String, String> request) {
        logger.info("=== 创建新对话会话请求 ===");
        
        try {
            String username = request.get("username");
            logger.info("原始用户名: {}", username);
            
            // 处理空用户名：为匿名用户生成临时标识
            if (username == null || username.trim().isEmpty()) {
                username = "anonymous_" + System.currentTimeMillis();
                logger.info("生成匿名用户临时标识: {}", username);
            }
            
            // 创建新会话
            logger.info("开始创建新会话，用户: {}", username);
            boolean success = chatService.createNewSession(username);
            
            // 构建响应
            Map<String, Object> response = new HashMap<>();
            if (success) {
                response.put("success", true);
                response.put("message", "新对话创建成功");
                logger.info("新会话创建成功，用户: {}", username);
            } else {
                response.put("success", false);
                response.put("message", "创建新对话失败");
                logger.warn("新会话创建失败，用户: {}", username);
            }
            
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            // 异常处理：记录详细错误信息
            logger.error("创建新对话失败: {}", e.getMessage(), e);
            
            // 返回用户友好的错误信息
            Map<String, Object> response = new HashMap<>();
            response.put("success", false);
            response.put("message", "创建新对话时发生错误");
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
        }
    }

} 